/**
 * Copyright (C) 2016 X-Forever.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.macrossx.server.controller;

import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;

import javax.imageio.ImageIO;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import com.macrossx.springframework.common.MapResponse;
import com.macrossx.springframework.validation.PhoneValidation;

import net.sf.oval.Validator;

@Controller
@RequestMapping(value = "/client")
public class ExampleConttoller {
	@Autowired
	private Validator validator;

	@RequestMapping(value = "/test", method = RequestMethod.GET, produces = { "application/json" })
	@ResponseBody
	public MapResponse login(@RequestParam(value = "appName", required = true) String appName) {

		return new MapResponse(validator.validate(new PhoneValidation(appName)));
	}

	@RequestMapping(value = "/test2", method = RequestMethod.GET, produces = { "application/json" })
	public String login2(@RequestParam(value = "appName", required = true) String appName,
			@RequestParam(value = "appType", required = true) String appType) {

		return "/aaa/index";
	}

	public static void main(String... s) throws IOException {
		BufferedImage bimage = ImageIO
				.read(new File("F:\\synctoy\\git-storage\\OCR-java\\src\\main\\resources\\image\\image.jpg"));

		BufferedImage toR = new BufferedImage(bimage.getWidth(), bimage.getHeight(), BufferedImage.TYPE_INT_RGB);
		BufferedImage toG = new BufferedImage(bimage.getWidth(), bimage.getHeight(), BufferedImage.TYPE_INT_RGB);
		BufferedImage toB = new BufferedImage(bimage.getWidth(), bimage.getHeight(), BufferedImage.TYPE_INT_RGB);
//		BufferedImage toRC = new BufferedImage(bimage.getWidth(), bimage.getHeight(), BufferedImage.TYPE_INT_RGB);
//		BufferedImage toGC = new BufferedImage(bimage.getWidth(), bimage.getHeight(), BufferedImage.TYPE_INT_RGB);
//		BufferedImage toBC = new BufferedImage(bimage.getWidth(), bimage.getHeight(), BufferedImage.TYPE_INT_RGB);
		BufferedImage to = new BufferedImage(bimage.getWidth(), bimage.getHeight(), BufferedImage.TYPE_INT_RGB);
		

		int[][] ri = new int[bimage.getWidth()][bimage.getHeight()];

		int[][] gi = new int[bimage.getWidth()][bimage.getHeight()];
		int[][] bi = new int[bimage.getWidth()][bimage.getHeight()];
		for (int x = 0; x < bimage.getWidth(); x++) {
			for (int y = 0; y < bimage.getHeight(); y++) {
				int[] rgb = getRGB(bimage.getRGB(x, y));
				int[] r = new int[3], g = new int[3], b = new int[3];
				r[0] = rgb[0];
				r[1] = r[2] = 0;
				g[1] = rgb[1];
				g[0] = g[2] = 0;
				b[2] = rgb[2];
				b[0] = b[1] = 0;
				ri[x][y] = rgb[0];
				gi[x][y] = rgb[1];
				bi[x][y] = rgb[2];
				toR.setRGB(x, y, toRGB(r));
				toG.setRGB(x, y, toRGB(g));
				toB.setRGB(x, y, toRGB(b));
			}
		}
		ImageIO.write(toR, "jpg", new File("d:\\test1-R.jpg"));
		ImageIO.write(toG, "jpg", new File("d:\\test1-G.jpg"));
		ImageIO.write(toB, "jpg", new File("d:\\test1-B.jpg"));
		int otsuR = otsuCal(ri), otsuG = otsuCal(gi), otsuB = otsuCal(bi);
		System.out.println(otsuCal(ri) + "," + otsuCal(gi) + "," + otsuCal(bi));
		BufferedImage R = otsuImageColor(bimage,otsuR,0,true);
		BufferedImage G = otsuImageColor(bimage,otsuG,1,true);
		BufferedImage B = otsuImageColor(bimage,otsuB,2,true);
		ImageIO.write(R, "jpg", new File("d:\\test1-otsuR.jpg"));
		ImageIO.write(G, "jpg", new File("d:\\test1-otsuG.jpg"));
		ImageIO.write(B, "jpg", new File("d:\\test1-otsuB.jpg"));
		
		for (int x = 0; x < bimage.getWidth(); x++) {
			for (int y = 0; y < bimage.getHeight(); y++) {
				int[] rgb = getRGB(R.getRGB(x, y));
				int[] r = new int[3], g = new int[3], b = new int[3];
				r[0] = rgb[0];
				r[1] = r[2] = 0;
				g[1] = rgb[1];
				g[0] = g[2] = 0;
				b[2] = rgb[2];
				b[0] = b[1] = 0;
				ri[x][y] = rgb[0];
				gi[x][y] = rgb[1];
				bi[x][y] = rgb[2];
				toR.setRGB(x, y, toRGB(r));
				toG.setRGB(x, y, toRGB(g));
				toB.setRGB(x, y, toRGB(b));
			}
		}
		otsuB = otsuCal(bi);
		System.out.println(otsuB);
		otsuG = otsuCal(gi);
		System.out.println(otsuG);
		ImageIO.write(otsuImageColor(R,otsuB,2,false), "jpg", new File("d:\\test1-otsuRb1.jpg"));
			
		for (int x = 0; x < bimage.getWidth(); x++) {
			for (int y = 0; y < bimage.getHeight(); y++) {
				int[] rgb = getRGB(bimage.getRGB(x, y));
				if(rgb[0]<=otsuR&& rgb[1]<=otsuG&& rgb[2]<=otsuB){
					to.setRGB(x, y, toRGB(new int[]{255,255,255}));
				}else{
					to.setRGB(x, y, toRGB(new int[]{0,0,0}));
				}
			}
		}
		ImageIO.write(to, "jpg", new File("d:\\test1-to.jpg"));
		BufferedImage toa = new BufferedImage(bimage.getWidth(), bimage.getHeight(), BufferedImage.TYPE_INT_RGB);
		BufferedImage tod = new BufferedImage(bimage.getWidth(), bimage.getHeight(), BufferedImage.TYPE_INT_RGB);
		int[]ax=new int[256],ay=new int[256];
		BufferedImage dr = new BufferedImage(bimage.getWidth(), bimage.getHeight(), BufferedImage.TYPE_INT_RGB);
		for (int x = 0; x < bimage.getWidth(); x++) {
			for (int y = 0; y < bimage.getHeight(); y++) {
				int[] pr = getRGB(R.getRGB(x, y));
				int[] pg = getRGB(G.getRGB(x, y));
				if(pg[1]-pr[0]>0){
					to.setRGB(x, y, toRGB(new int[]{255,255,255}));
				}else{
					to.setRGB(x, y, toRGB(new int[]{0,0,0}));
				}
				int p = pr[0];
				ax[p] = ax[p]+1;
				p = pg[1];
				ay[p] = ay[p]+1;
			}
		}		
		ImageIO.write(to, "jpg", new File("d:\\d-r.jpg"));

		StringBuffer sbr = new StringBuffer("R"),sbg=new StringBuffer("G");
		for(int x=0;x<256;x++){
			if(ax[x]>0)sbr.append("["+x+":"+ax[x]+"],");
			if(ay[x]>0)sbg.append("["+x+":"+ay[x]+"],");
		}
		System.out.println(sbr+"\n"+sbg);
//		ImageIO.write(toG, "jpg", new File("d:\\test1-otsuG.jpg"));
//		ImageIO.write(toB, "jpg", new File("d:\\test1-otsuB.jpg"));

		// ImageIO.write(toG, "jpg", new File("d:\\test1-g.jpg"));
		 ImageIO.write(toa, "jpg", new File("d:\\test1-toa.jpg"));
		 ImageIO.write(tod, "jpg", new File("d:\\test1-tod.jpg"));
	}

	public static int[] getRGB(int pixel) {
		int[] rgb = new int[3];
		rgb[0] = (pixel & 0xff0000) >> 16;
		rgb[1] = (pixel & 0xff00) >> 8;
		rgb[2] = (pixel & 0xff);
		return rgb;
	}

	public static int toRGB(int[] rgb) {
		return (rgb[0] << (16 & 0xff)) | (rgb[1] << (8 & 0xff)) | (rgb[2] & 0xff);
	}

	public static int otsuCal(int[][] input) {
		int GrayScale = 256;
		int width = input.length;
		int height = input[0].length;
		int[] pixelCount = new int[256];
		float[] pixelPro = new float[256];
		int i, j, pixelSum = width * height, threshold = 0;
		for (i = 0; i < GrayScale; i++) {
			pixelCount[i] = 0;
			pixelPro[i] = 0;
		}

		for (i = 0; i < width; i++) {
			for (j = 0; j < height; j++) {
				// System.out.print(input[i][j]+",");
				// System.out.println( input[i][j]+","+
				// pixelCount[input[i][j]]);
				pixelCount[input[i][j]] = pixelCount[input[i][j]] + 1;
			}
		}
		// 计算每个像素在整幅图像中的比例
		float maxPro = 0.0f;
		int kk = 0;
		for (i = 0; i < GrayScale; i++) {
			pixelPro[i] = (float) pixelCount[i] / pixelSum;
			if (pixelPro[i] > maxPro) {
				maxPro = pixelPro[i];
				kk = i;
			}
		}
		// 遍历灰度级[0,255]
		float w0, w1, u0tmp, u1tmp, u0, u1, u, deltaTmp, deltaMax = 0;
		for (i = 0; i < GrayScale; i++) {
			w0 = w1 = u0tmp = u1tmp = u0 = u1 = u = deltaTmp = 0;
			for (j = 0; j < GrayScale; j++) {
				if (j <= i) // 背景部分
				{
					w0 += pixelPro[j];
					u0tmp += j * pixelPro[j];
				} else // 前景部分
				{
					w1 += pixelPro[j];
					u1tmp += j * pixelPro[j];
				}
			}
			u0 = u0tmp / w0;
			u1 = u1tmp / w1;
			u = u0tmp + u1tmp;
			deltaTmp = (float) (w0 * Math.pow((u0 - u), 2) + w1 * Math.pow((u1 - u), 2));
			if (deltaTmp > deltaMax) {
				deltaMax = deltaTmp;
				threshold = i;
			}
		}

		return threshold;
	}
	
	public static BufferedImage otsuImage(BufferedImage input,int otsuThread,int poz,boolean flag){
		BufferedImage to = new BufferedImage(input.getWidth(), input.getHeight(), BufferedImage.TYPE_INT_RGB);
		for (int x = 0; x < input.getWidth(); x++) {
			for (int y = 0; y < input.getHeight(); y++) {
				int[] rgb = getRGB(input.getRGB(x, y));
				if(flag){
				if (rgb[poz] <= otsuThread) {
					to.setRGB(x, y, toRGB(new int[]{255,255,255}));
				} else {
					to.setRGB(x, y, toRGB(new int[] { 0, 0, 0 }));
				}
				}else{
					if (rgb[poz] >= otsuThread) {
						to.setRGB(x, y, toRGB(new int[]{255,255,255}));
					} else {
						to.setRGB(x, y, toRGB(new int[] { 0, 0, 0 }));
					}
				}
			}
		}
		return to;
	}
	public static BufferedImage otsuImageColor(BufferedImage input,int otsuThread,int poz,boolean flag){
		BufferedImage to = new BufferedImage(input.getWidth(), input.getHeight(), BufferedImage.TYPE_INT_RGB);
		for (int x = 0; x < input.getWidth(); x++) {
			for (int y = 0; y < input.getHeight(); y++) {
				int[] rgb = getRGB(input.getRGB(x, y));
				if(flag){
				if (rgb[poz] <= otsuThread) {
					to.setRGB(x, y,input.getRGB(x, y));
				} else {
					to.setRGB(x, y, toRGB(new int[] { 0, 0, 0 }));
				}
				}else{
					if (rgb[poz] >= otsuThread) {
						to.setRGB(x, y, toRGB(rgb));
					} else {
						to.setRGB(x, y, toRGB(new int[] { 0, 0, 0 }));
					}
				}
			}
		}
		return to;
	}
}
